package com.missilike.biz.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.missilike.biz.*;
import com.missilike.core.domain.RewardAccountRequest;
import com.missilike.core.enums.MilPushType;
import com.missilike.core.exception.BizException;
import com.missilike.core.result.BizResultCode;
import com.missilike.domain.request.MilPushForm;
import com.missilike.repository.entity.MilAccount;
import com.missilike.repository.entity.MilAccountContent;
import com.missilike.repository.entity.MilContentAppreciate;
import com.missilike.repository.entity.MilRewardRecord;
import com.missilike.repository.entity.extend.MilContentAppreciateExtend;
import com.missilike.repository.mapper.MilContentAppreciateMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author pengpengli
 * @since 2018-12-19
 */
@Service
public class MilContentAppreciateServiceImpl extends ServiceImpl<MilContentAppreciateMapper, MilContentAppreciate> implements IMilContentAppreciateService {

    private final IMilAccountContentService accountContentService;
    private final IMilAccountService accountService;
    private final IMilEquipmentService iMilEquipmentService;
    private final IMilRewardRecordService milRewardRecordService;


    @Autowired
    public MilContentAppreciateServiceImpl(IMilRewardRecordService milRewardRecordService, IMilAccountContentService accountContentService, MilAccountServiceImpl accountService, IMilEquipmentService iMilEquipmentService) {
        this.accountContentService = accountContentService;
        this.accountService = accountService;
        this.iMilEquipmentService = iMilEquipmentService;
        this.milRewardRecordService = milRewardRecordService;
    }

    @PostConstruct
    public void init() {
        accountContentService.setAppreciateService(this);
        accountContentService.setEquipmentService(iMilEquipmentService);
        milRewardRecordService.setAccountService(accountService);
    }

    public boolean rewardAccounts(RewardAccountRequest request) {
        MilAccount account = accountService.getById(request.getAccountId());
        if (account == null) {
            throw new BizException(BizResultCode.NO_ACCOUNT);
        }
        if (account.getBalance().setScale(2, BigDecimal.ROUND_HALF_DOWN)
                .subtract(account.getLastBalance().setScale(2, BigDecimal.ROUND_HALF_DOWN))
                .compareTo(account.getLastBalance().setScale(2, BigDecimal.ROUND_HALF_DOWN)) == -1) {
            throw new BizException(BizResultCode.ACCOUNT_INSUFFICIENT_BALANCE);
        }
        MilAccountContent content = accountContentService.getById(request.getContentId());
        if (content == null) {
            throw new BizException(BizResultCode.ACCOUNT_ARTICLE_NO_EXIST);
        }
        save(new MilContentAppreciate(account.getId(), request.getContentId()));
        account.setBalance(account.getBalance().subtract(account.getLastBalance().add(account.getRewardIncrease())));
        account.setLastBalance(account.getLastBalance().add(account.getRewardIncrease()));
        accountService.updateById(account);

        MilRewardRecord record = new MilRewardRecord();
        record.setAccountId(account.getId());
        record.setCreateTime(LocalDateTime.now());
        record.setRewardContentId(content.getId());
        record.setRewardAccountId(content.getAccountId());
        record.setRewardBalance(account.getRewardIncrease());
        milRewardRecordService.save(record);

        //todo 推送
        MilPushForm milPushForm = new MilPushForm();
        milPushForm.setAccountId(request.getAccountId());
        milPushForm.setContentId(request.getContentId());
        milPushForm.setType(MilPushType.REWARD.getValue());
        iMilEquipmentService.publishMassage(milPushForm);

        return true;
    }

    @Override
    public List<MilContentAppreciateExtend> getAppreciates(Long id) {
        return baseMapper.getAppreciateUsers(id);
    }
}
